package com.fashion.web.filter;

import com.fashion.utils.StringUtils;
import com.fashion.web.response.HtmlResponseWrapper;
import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.InvalidParameterException;

/**
 * User: Administrator
 * Date: 11-12-7
 * Time: 上午10:30
 */
public class HtmlFilter implements Filter {
    private ServletContext context;
    private static final Logger logger = Logger.getLogger(HtmlFilter.class);
    private String persistentFolder;
    private String oldPersistentFolder;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.context = filterConfig.getServletContext();
        persistentFolder = context.getRealPath(StringUtils.Persistent_Html_Folder);
        oldPersistentFolder = context.getRealPath("/oldHtml");

        File folder = new File(persistentFolder);
        if (!folder.exists()) {
            if (!folder.mkdir()) {
                logger.error("Can not create persistence folder: " + StringUtils.Persistent_Html_Folder);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getRequestURI();
        String serverName = request.getServerName();
        int endIndex = serverName.indexOf(".");
        String domain = serverName;
        if (endIndex > 0) {
            domain = serverName.substring(0, endIndex);
        }

        if (uri.endsWith("html")) {
            if (isTagCloudHtml(servletRequest, servletResponse, filterChain, response, uri)) {
                return;
            }

            if (!handleAsOldHtml(response, uri)) {
                handleHtml(servletRequest, servletResponse, filterChain, request, response, uri);
            }
        } else if (uri.endsWith("/")) {
            handleAsIndex(servletRequest, servletResponse, filterChain, response, domain);
        } else {
            try {
                filterChain.doFilter(servletRequest, servletResponse);
            } catch (ServletException ex) {
                logger.error("should be ClientAbortException for url: " + uri + ", details: " + ex.getMessage());
                request.getRequestDispatcher("/management/error.action").forward(request, response);
            } catch (Exception e) {
                logger.error("should be handled exception caught in htmlfilter for url: " + uri, e);
                logger.error("url is: " + request.getRequestURL());
                request.getRequestDispatcher("/management/error.action").forward(request, response);
            }
        }
    }

    private boolean isTagCloudHtml(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain, HttpServletResponse response, String uri) throws IOException, ServletException {
        if (uri.equalsIgnoreCase(StringUtils.TagCloudHtmlUrl)) {
            String fileName = persistentFolder + File.separator + StringUtils.TagCloudHtmlName;
            File htmlFile = new File(fileName);
            if (!htmlFile.exists()) {
                HtmlResponseWrapper wrapper = new HtmlResponseWrapper((HttpServletResponse) servletResponse);
                filterChain.doFilter(servletRequest, wrapper);
                wrapper.getWriter().flush();
                String responseContent = wrapper.toString();

                if (!responseContent.contains("很抱歉，您访问的页面不存在")) {
                    logger.info("start to save tagcanvas html file");

                    saveHtml(responseContent, fileName);
                }

                response.getWriter().print(responseContent);

            }else{
              responseWithFile(response,htmlFile);
            }

            return true;
        }

        return false;
    }

    protected void handleHtml(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain, HttpServletRequest request, HttpServletResponse response, String uri) throws IOException, ServletException {
        if (StringUtils.isHtmlExpression(uri)) {
            String preFolder = StringUtils.findPreFolder(uri);
            String preFolderPath = persistentFolder + File.separator + preFolder;
            String fileName = StringUtils.findHtmlName(uri);
            String htmlFileName = preFolderPath + File.separator + fileName;
            File htmlFile = new File(htmlFileName);
            if (!htmlFile.exists()) {
                HtmlResponseWrapper wrapper = new HtmlResponseWrapper((HttpServletResponse) servletResponse);
                filterChain.doFilter(servletRequest, wrapper);
                wrapper.getWriter().flush();
                String responseContent = wrapper.toString();
                if (!responseContent.contains("很抱歉，您访问的页面不存在")) {
                    logger.info("start to save news html file for url: " + uri);
                    File folderFile = new File(preFolderPath);
                    if (!folderFile.exists()) {
                        folderFile.mkdirs();
                    }

                    saveHtml(responseContent, preFolderPath + File.separator + fileName);
                }

                response.getWriter().print(responseContent);

                //comment this line if we want to save html files
                //     filterChain.doFilter(servletRequest, servletResponse);

                return;
            }

            responseWithFile(response, htmlFile);
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    protected void handleAsIndex(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain, HttpServletResponse response, String domain) throws IOException, ServletException {
      /*  String name = findIndexName(domain);
        File indexHtml = new File(persistentFolder + File.separator + name);
        if (indexHtml.exists() && indexHtml.isFile()) {
            logger.debug("found index html file for url: " + domain);
            responseWithFile(response, indexHtml);
        } else {*/
            filterChain.doFilter(servletRequest, servletResponse);
//        }
    }

    protected String findIndexName(String domain) {
        if ("www".equalsIgnoreCase(domain) || "localhost".equalsIgnoreCase(domain) || "fengsung".equalsIgnoreCase(domain)) {
            return "index.html";
        } else if ("pic".equalsIgnoreCase(domain)) {
            return "pic_index.html";
        } else if ("luxury".equalsIgnoreCase(domain)) {
            return "luxury_index.html";
        } else if ("fashion".equalsIgnoreCase(domain)) {
            return "fashion_index.html";
        } else if ("life".equalsIgnoreCase(domain)) {
            return "life_index.html";
        } else if ("brand".equalsIgnoreCase(domain)) {
            return "brand_index.html";
        } else if ("news".equalsIgnoreCase(domain)) {
            return "news_index.html";
        }

        return "";
    }

    protected boolean handleAsOldHtml(HttpServletResponse response, String uri) throws IOException, ServletException {
        File oldHtml = fetchOldHtml(uri);
        if (oldHtml.exists()) {
            logger.debug("found old html file: " + oldHtml.getName() + " for url: " + uri);
            responseWithFile(response, oldHtml);

            return true;
        }

        return false;
    }

    protected File fetchOldHtml(String uri) {
        return new File(oldPersistentFolder + File.separator + uri.substring(1));
    }

    protected void responseWithFile(HttpServletResponse response, File htmlFile) throws IOException {
        //   String mimeType = context.getMimeType(request.getRequestURI());
        //    response.setContentType(mimeType);
        response.setContentType("text/html");
        FileInputStream inputStream = new FileInputStream(htmlFile);
        ServletOutputStream outputStream = response.getOutputStream();

        for (int i = inputStream.read(); i != -1; i = inputStream.read()) {
            outputStream.write((byte) i);
        }

        inputStream.close();
    }


    protected String generateFileName(String uri) {
        String preFolder = StringUtils.findPreFolder(uri);
        String preFolderPath = persistentFolder + File.separator + preFolder;
        /*File folderFile = new File(preFolderPath);
        if(!folderFile.exists()) {
            logger.info("create folder: " + preFolderPath);
            folderFile.mkdirs();
        }*/

        String fileName = StringUtils.findHtmlName(uri);

        return preFolderPath + File.separator + fileName;
    }

    protected void saveHtml(String html, String fileName) {
        File htmlFile = new File(fileName);
        OutputStreamWriter out = null;
        try {
            out = new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8");
            out.write(html);
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("Error saving html file: " + e.getMessage());
        }
    }

    protected String forwardToSecondDomain(String secondDomainName) {
        if ("news".equalsIgnoreCase(secondDomainName)) {
            return "/management/news/newsIndex.action";
        } else if ("pic".equalsIgnoreCase(secondDomainName)) {
            return "/gallery/index.action";
        }

        throw new InvalidParameterException("Do not support this second domain name!");
    }


    //   protected void wrapResponse() {
//            if (!htmlFile.exists()) {
//                ResponseWrapper wrapper = new ResponseWrapper(response);
//                filterChain.doFilter(servletRequest, wrapper);
//                saveHtml(wrapper.toString(), fileName);
//            }
//
//            String mimeType = context.getMimeType(request.getRequestURI());
//            response.setContentType(mimeType);
////            servletResponse.setContentType("text/html");
//            FileInputStream inputStream = new FileInputStream(htmlFile);
//            ServletOutputStream outputStream = response.getOutputStream();
//
//            for (int i = inputStream.read(); i != -1; i = inputStream.read()) {
//                outputStream.write((byte) i);
//            }

    @Override
    public void destroy() {
        this.context = null;
    }
}
